Skip to content

fix(alfred): read a large decimal subaccount ID as decimal - #8030

Open
yhabib wants to merge 3 commits into
mainfrom
fix/alfred-icrc-account-hex-reinterpret
Open

fix(alfred): read a large decimal subaccount ID as decimal#8030
yhabib wants to merge 3 commits into
mainfrom
fix/alfred-icrc-account-hex-reinterpret

Conversation

@yhabib

@yhabib yhabib commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Motivation

The Alfred "Encode ICRC-1 Account" util read a large decimal subaccount ID with Number(). Above Number.MAX_SAFE_INTEGER, it silently re-read the same digit string as hexadecimal. A user who typed the decimal 18446744073709551615 got the account for hex 0x18446744073709551615, a different subaccount. Funds sent to that address land on the wrong subaccount.

Changes

  • Rewrote parseDecimalSubAccount to convert every all-digit ID with BigInt and write it big-endian into the 32-byte subaccount.
  • Added a digit-length guard that rejects an ID over 78 digits before the BigInt conversion, so a long pasted string cannot slow the input.
  • Added five component tests for the decimal path, and a test.fixme Playwright spec that documents the end-to-end check once the local replica works again.
  • Moved the changelog entry to the Security section.

Tests

Added tests cover the value above MAX_SAFE_INTEGER, the "never read as hex" case, a value above 32 bytes, a very long digit string, and leading zeros. npx vitest run passes: 673 test files, 5910 tests, 9 skipped. npm run check and npx eslint --max-warnings 0 . both pass with 0 errors.

Todos

  • Accessibility (a11y) – no impact.
  • Changelog – added, under Security.

The Encode ICRC-1 Account utility read an all-digit subaccount ID with
Number(). Above Number.MAX_SAFE_INTEGER it re-read the same digit string
as hexadecimal. A user who typed the decimal 18446744073709551615 got the
account for 0x18446744073709551615. A deposit then landed on a different
ICRC-1 subaccount than the user intended.

The utility now converts every all-digit ID with BigInt and writes the
value big-endian into the 32-byte subaccount. Small IDs keep the result
that SubAccount.fromID gave. An ID that needs more than 32 bytes raises
the existing subaccount error.

A digit-length guard rejects an ID with more than 78 significant digits
before the BigInt conversion. The largest 32-byte value has 78 decimal
digits, so a longer string cannot be valid. The guard also stops a long
pasted string from blocking the tab in BigInt.
The spec opens the util from the command palette and checks that a decimal
subaccount ID above Number.MAX_SAFE_INTEGER encodes as decimal. It also
checks the largest subaccount, the error above 32 bytes, and that a
200000 character paste shows the error inside 3 seconds.

The spec is test.fixme. No local replica runs on this machine, because
dfx 0.32.0 ships pocket-ic-server 13.0.0 and that server rejects the saved
snsdemo snapshot state. Remove .fixme when the replica starts again.
@yhabib
yhabib requested a review from a team as a code owner September 3, 2026 16:10
@yhabib
yhabib requested a lite review from Copilot September 3, 2026 16:10
@zeropath-ai

zeropath-ai Bot commented Sep 3, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 8fc8370.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► frontend/src/lib/components/alfred/BuildIcrcAccountUtil.svelte
    Add decimal subaccount parsing with validation and large decimal handling; support for 32-byte subaccounts; adjust parsing to use decimal path for large numbers
Enhancement ► frontend/src/tests/e2e/alfred-icrc-account.spec.ts
    Add end-to-end tests for Encode ICRC-1 Account util including decimal subaccount handling and edge cases
Enhancement ► frontend/src/tests/lib/components/alfred/BuildIcrcAccountUtil.spec.ts
    Update unit tests to cover decimal subaccount encoding, decimal vs hex handling, large subaccount errors, and leading zeros behavior

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The current parsing order still treats 64-character all-digit inputs as hex (reintroducing “decimal read as hex” behavior for that case), and should be corrected before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes a security-relevant parsing bug in the Alfred “Encode ICRC-1 Account” utility where large all-digit subaccount IDs could be misinterpreted as hexadecimal, producing the wrong ICRC account text and potentially misdirecting deposits.

Changes:

  • Updated subaccount parsing to treat all-digit inputs as decimal via BigInt, with a digit-length guard to avoid expensive conversions on long pasted strings.
  • Added component tests covering large decimal values, hex-vs-decimal correctness, overflow, very long input, and leading zeros.
  • Added a (currently test.fixme) Playwright e2e spec documenting end-to-end behavior and the long-paste responsiveness requirement; moved changelog entry under Security.
File summaries
File Description
frontend/src/lib/components/alfred/BuildIcrcAccountUtil.svelte Switches decimal parsing to BigInt-based conversion with digit-length guard.
frontend/src/tests/lib/components/alfred/BuildIcrcAccountUtil.spec.ts Adds component tests for the corrected decimal parsing path and guard behavior.
frontend/src/tests/e2e/alfred-icrc-account.spec.ts Adds an e2e (fixme) spec documenting palette reachability and long-input responsiveness.
CHANGELOG-Nns-Dapp-unreleased.md Records the change under the Security section.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread frontend/src/lib/components/alfred/BuildIcrcAccountUtil.svelte
Comment thread frontend/src/tests/e2e/alfred-icrc-account.spec.ts Outdated
Comment thread frontend/src/tests/e2e/alfred-icrc-account.spec.ts Outdated
Remove the wall-clock duration assertion on the very long paste step.
It can flake across CI machines. The functional assertion, that the
error shows, still covers the guard.

Add a KEY_DEBOUNCE_MS constant for the Escape key delay. This matches
the pattern in mobile-alfred.spec.ts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XCBQvbTVxZ26fQiSsxSuGW

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The parsing change is bounded and validated by focused component tests covering the reported failure mode and key edge cases.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants